#include "dpLibrary\dpWindows.h"
#include "dpLibrary\graphics.h"
#include "dpLibrary\audio.h"

#include "winlib.h"
#include <time.h>

#include "AFGraphics.h"
#include "AFInput.h"
#include "AFObjectFactory.h"
#include "AFDebugging.h"

#ifdef _DEBUG
#pragma comment(lib, "dpLibrary/dpLibraryDebug.lib")
#else
#pragma comment(lib, "dpLibrary/dpLibrary.lib")
#endif

#define ClientWidth 800
#define ClientHeight 600


dpGraphics* graphicsSystem = NULL;
dpAudio* audio = NULL;
dpPixel* screenBuffer = NULL;

uint GameIsRunning = 1;
int InputReceived = 0;

//The message handling procedure for the game
LRESULT WINAPI MessageHandler(HWND hWnd,   //The window the message is for (ours in this case)
                              UINT msg,   //The message type
                              WPARAM wParam, //The primary data for the message
                              LPARAM lParam) //The secondary data for the message (if any)
{

  DWORD dwAltKeyMask = 0;
  //See what type of message it is
  switch(msg)
  {  
  case WM_CHAR: //A character key was pressed
    {

      break;
    }
  case WM_SIZE:
    {
      int clientWidth  = LOWORD(lParam); 
      int clientHeight = HIWORD(lParam);
      dpResize(graphicsSystem, clientWidth, clientHeight);
      break;
    }
  case WM_KEYDOWN:
    {
      //change key values to true when key is down
      switch(wParam)
      {
      case 'W':
        keyboard.wKey = 1;        
        break;
      case 'A':
        keyboard.aKey = 1;        
        break;
      case 'S':
        keyboard.sKey = 1;        
        break;
      case 'D':
        keyboard.dKey = 1;        
        break;
      case 'R':
        keyboard.rKey = 1;
        break;
      case 'Y':
        keyboard.yKey = 1;
        break;
      case 'T':
        keyboard.tKey = 1;
        break;
      case VK_SPACE:
        keyboard.spaceKey = 1;
        break;
      case VK_ESCAPE:
        GameIsRunning = 0;
        break;            
      }
      break; 
    }
  case WM_KEYUP:
    {
      //change key values to false when that key is lifted
      switch(wParam)
      {
      case 'W':
        keyboard.wKey = 0;
        break;
      case 'A':
        keyboard.aKey = 0;
        break;
      case 'S':
        keyboard.sKey = 0;
        break;
      case 'D':
        keyboard.dKey = 0;
        break;
      case 'R':
        keyboard.rKey = 0;
        break;
      case 'Y':
        keyboard.yKey = 0;
        break;
      case 'T':
        keyboard.tKey = 0;
        break;
      case VK_SPACE:
        keyboard.spaceKey = 0;
        break;
      }
      break;
    }
  case WM_CLOSE:
    {
      GameIsRunning = 0;
      break;
    }
  case WM_SYSKEYDOWN:
    {
      //Eat the WM_SYSKEYDOWN message to prevent freezing the game when
      //the alt key is pressed
      switch( wParam )
      {
      case VK_LMENU:
      case VK_RMENU:
        return 0;
      case VK_F4:
        //Check for Alt F4
        dwAltKeyMask = ( 1 << 29 );
        if( ( lParam & dwAltKeyMask ) != 0 )
          PostQuitMessage(0);
        return 0;
      }
      return 0;//
    }
  default:
    //We didn't completely handle the message, so pass it on for 
    //Windows to handle.
    return DefWindowProc(hWnd, msg, wParam, lParam);
  }
  return 0;
}

INT WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, 
                   LPSTR commandLine, INT commandShow)
{
  HWND windowHandle = 0;

  Sprite* player         = CreateSprite(ORANGE, CENTER_OF_SCREEN_X, 
    CENTER_OF_SCREEN_Y, 25000, 25000, 20, 20);  
  Sprite* enemyList      = CreateSprite(BLACK, 0, 0, 25000, 25000, 0, 0);
  /*Sprite* collisionTest  = CreateSprite(GREEN, 160, 120, 10, 10);*/
  Sprite* enemyListHead = enemyList;    

  AFDebugConsole();

  windowHandle = InitializeWindows(instance, MessageHandler, ClientWidth, 
    ClientHeight);

  graphicsSystem = dpInitializeGraphics(windowHandle, ClientWidth, 
    ClientHeight);

  screenBuffer = (dpPixel*)AFInitializeGraphics();

  audio = dpInitializeAudio();	

  /* initialize random seed: */
  srand ((unsigned int)time(NULL));
  //int rNum = (rand() % 310 + 1);  //give me a wierd semi colon related error??

  while(GameIsRunning)
  {
    WindowsSystemUpdate();
    ClearBuffer();		

    if (keyboard.wKey || keyboard.aKey || keyboard.sKey || keyboard.dKey)
    {
      InputReceived = 1;
    }
    else
    {
      InputReceived = 0;
    }
    
    /*UpdateScreenCoordinates(player, enemyListHead);    */

    CollisionDetection(player, enemyListHead);
    UpdateGraphics(player, enemyListHead);

    // Prints the player's location in the world in the
    // debug window.
    if(InputReceived)
    {
      printf("Player coordinates:\n");
      printf("screenX: %i ", player->screen.X);
      printf("screenY: %i ", player->screen.Y);
      printf("worldX: %i ",  player->world.X);
      printf("worldY: %i \n", player->world.Y);
    }    

    //input logic
    if(keyboard.wKey)
    {      
      player->world.Y -= 2;
    }
    if(keyboard.aKey)
    {     
      player->world.X -= 2;      
    }
    if(keyboard.sKey)
    {     
      player->world.Y += 2;
    }
    if(keyboard.dKey)
    {     
      player->world.X += 2;
    }
    if(keyboard.rKey)
    {
      /*int sxRandom = rand() % 310 + 1;
      int syRandom = rand() % 310 + 1;    */  
      int wxRandom = (rand() % dpScreenWidth  + 1) + 
        (player->world.X - (dpScreenWidth  / 2) );
      int wyRandom = (rand() % dpScreenHeight + 1) + 
        (player->world.Y - (dpScreenHeight/ 2) );      
      
      enemyList->next = CreateSprite(BLACK, 0, 0, 
        wxRandom, wyRandom, 20, 20);
      enemyList = enemyList->next;      
    }
    if(keyboard.yKey)
    {
      PrintRandomSprites();
    }
    if(keyboard.tKey)
    {
      CheckeredPattern();
    }
    if(keyboard.spaceKey)
    { 
      FireUpward(player);
    }

    dpUpdateAudio(audio);

    dpUpload(graphicsSystem, screenBuffer);
    dpRender(graphicsSystem);
  }
  dpShutdownAudio(audio);
  dpShutdownGraphics(graphicsSystem);
}

